package com.xinz.protocal.client;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import com.xinz.protocal.Buffer;
import com.xinz.protocal.Log;
import com.xinz.protocal.SrmiClient;
import com.xinz.protocal.SrmiDefine;
import com.xinz.protocal.config.ConfigFactory;

/**
 * SRMI Socket连接客户端的简单实现
 * 初始化之后通过connect方法来连接服务端<br>
 * 一个SimpleSocketClient对象对应一个连接session。<br>
 * 目前方法调用是单通道的，这也意味着同一时刻只有一个方法被调用
 * 
 * @author xingyun
 *
 */
public class SimpleHttpClient extends SrmiClient{
	
	URL url;
	
	long sessionId;

	public SimpleHttpClient(URL url, ConfigFactory factory) {
		super(factory);
		this.url = url;
	}

	@Override
	public Buffer request(Buffer request) throws IOException {
		request.type = SrmiDefine.TYPE_REQUEST;
		HttpURLConnection conn = null;
		InputStream is = null;
		try {
			conn = openConnection();
			OutputStream out =null;
			try {
				out = conn.getOutputStream();
				out.write(request.type);
				request.writeToStream(out);
				out.flush();
			}
			finally {
				if(out!=null) {
					out.close();
				}
			}
			is = conn.getInputStream();
			return doParse(is);
		} catch(IOException e) {
			Log.err("连接服务器失败！ url："+url);
			e.printStackTrace();
			throw e;
		}
		finally {
			try {
				is.close();
			}catch (Exception e) {
				
			}
			if(conn!=null) {
				conn.disconnect();
			}
		}
	}
	
	@Override
	public void run() {
		try {
			while(true) {
				try {
					Thread.sleep(1000);
					HttpURLConnection conn = openConnection();
					doParse(conn.getInputStream());
				}
				catch(Exception e) {
					e.printStackTrace();
				}
			}
		}
		catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	HttpURLConnection openConnection() throws IOException {
		HttpURLConnection conn = (HttpURLConnection)url.openConnection();
		conn.setRequestMethod("POST");
		conn.setDoInput(true);
		conn.setDoOutput(true);
//		conn.setReadTimeout(15000);
//		conn.setConnectTimeout(10000);
		conn.connect();
		DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
		dos.writeLong(sessionId);
		return conn;
	}

	Buffer doParse(InputStream is) throws IOException{
		DataInputStream dis = new DataInputStream(is);
		sessionId = dis.readLong();// 读取sessionId
		int pakSize = dis.readShort();
		Buffer result = null;
		for(int i = 0; i < pakSize; i++) {
			int type = dis.read();
			int length = dis.readShort();
			byte buff[] = new byte[length];
			dis.readFully(buff);
			Buffer buffer = new Buffer(buff, type);
			if(type == SrmiDefine.TYPE_REQUEST_NORETURN) {
				nativeInvoker.invoke(getSession(), buffer);
			}
			else if(type == SrmiDefine.TYPE_RETURN) {
				if(result != null) {
					throw new RuntimeException();
				}
				result = buffer;
			}
		}
		return result;
	}
}
